#include "Menu.h"
#include "Juego.h"
#include "ListaParametros.h"

WRAPPER_JUEGO Menu::wrapperPantallaJuego = 0;
WRAPPER_JUEGO_QUIT Menu::wrapperPantallaQuitJuego = 0;

void Menu::accionSalir(Widget* widget, const SDL_Event& event){
	SDLControls::getInstance()->stop();
}

void Menu::iniciarJuego(Widget* widget, const SDL_Event& event){
	string* loginP1;
	string* passP1;
	string* loginP2;
	string* passP2;

	//obtengo el login del 1er jugador
	loginP1 = Session::getInstance()->getPlayerOneLogin();

	//obtengo el pass del 1er jugador
	passP1 = Session::getInstance()->getPlayerOnePass();

	//obtengo el login del 2do jugador
	loginP2 = Session::getInstance()->getPlayerTwoLogin();

	//obtengo el pass del 2do jugador
	passP2 = Session::getInstance()->getPlayerTwoPass();

	//si falta alguno de los parametros aviso, si no valido
	if(loginP1 == NULL || loginP1->empty() || passP1 == NULL || passP1->empty() || loginP2 == NULL || loginP2->empty()  || passP2 == NULL || passP2->empty() ){
		Menu::popUp(new Label("Debe ingresar todos los parametros!"), &Menu::pantallaSeleccionJugadores);

		Session::getInstance()->setAttribute(PLAYER_ONE_PASSW_ATT, "");
		Session::getInstance()->setAttribute(PLAYER_TWO_PASSW_ATT, "");
	}
	else{
		if(DBService::getInstance()->isConexionCorrecta()){
			if(DBService::getInstance()->esLoginValido(*loginP1, *passP1, *loginP2, *passP2)){
				ListaParametros::getInstance()->setNombrePacman1(loginP1->c_str());
				ListaParametros::getInstance()->setNombrePacman2(loginP2->c_str());
				//Lo voy a disparar en el juego para evitar delay
				//DBService::getInstance()->iniciarJuegoEntre(*loginP1,*loginP2);

				//reinicio la sesion
				Session::getInstance()->clear();

				//limpio la pantalla
				SDLControls::getInstance()->clear();
				
				//doy comienzo al juego propiamente dicho
				if(Menu::wrapperPantallaJuego > 0)
					Menu::wrapperPantallaJuego(0);

				//actualizo la pantalla debido a que la resolucion del juego y la del menu no tienen porque ser iguales
				SDLControls::getInstance()->updateScreen();

				//vuelvo a mostrar el menu principal
				Menu::pantallaInicial();
			}
			else{
				//blanqueo los passwords
				Session::getInstance()->setAttribute(PLAYER_ONE_PASSW_ATT, "");
				Session::getInstance()->setAttribute(PLAYER_TWO_PASSW_ATT, "");

				//informo y vuelvo
				Menu::popUp(new Label("Datos no validos"), &Menu::pantallaSeleccionJugadores);
			}
		}
		else{
			Menu::popUp(new Label("Error en conexion a la BD"), &Menu::pantallaSeleccionJugadores);	
		}
	}
}

void Menu::pantallaSeleccionJugadores(Widget* widget, const SDL_Event& event){
	TextBox* txtPlayerOneLogin;
	PasswordTextBox* txtPlayerOnePass;
	TextBox* txtPlayerTwoLogin;
	PasswordTextBox* txtPlayerTwoPass;
	Button* btnStart;
	Button* btnBack;
	GridLayout* layout;

	//limpio la pantalla
	SDLControls::getInstance()->clear();

	//creo el campo de login para el 1er jugador
	txtPlayerOneLogin = new TextBox(Session::getInstance()->getPlayerOneLogin()!=NULL?Session::getInstance()->getPlayerOneLogin()->c_str():"");
	txtPlayerOneLogin->setCharWidth(20);
	txtPlayerOneLogin->setKeyDownHandler(&Session::setPlayerOneLogin);

	//creo el campo de password para el 1er jugador
	txtPlayerOnePass = new PasswordTextBox(Session::getInstance()->getPlayerOnePass()!=NULL?Session::getInstance()->getPlayerOnePass()->c_str():"");
	txtPlayerOnePass->setCharWidth(20);
	txtPlayerOnePass->setKeyDownHandler(&Session::setPlayerOnePass);

	//creo el campo de login para el 2do jugador
	txtPlayerTwoLogin = new TextBox(Session::getInstance()->getPlayerTwoLogin()!=NULL?Session::getInstance()->getPlayerTwoLogin()->c_str():"");
	txtPlayerTwoLogin->setCharWidth(20);
	txtPlayerTwoLogin->setKeyDownHandler(&Session::setPlayerTwoLogin);

	//creo el campo de password para el 2do jugador
	txtPlayerTwoPass = new PasswordTextBox(Session::getInstance()->getPlayerTwoPass()!=NULL?Session::getInstance()->getPlayerTwoPass()->c_str():"");
	txtPlayerTwoPass->setCharWidth(20);
	txtPlayerTwoPass->setKeyDownHandler(&Session::setPlayerTwoPass);

	//creo el boton para comenzar el juego
	btnStart = new Button("iniciar");
	btnStart->setWidth(80);
	btnStart->setClickHandler(&Menu::iniciarJuego);	

	//creo el boton para volver atras
	btnBack = new Button("volver");
	btnBack->setWidth(80);
	btnBack->setClickHandler(&Menu::pantallaInicial2);
	
	//creo un layout para organizar los controles
	layout = new GridLayout(2, 5);

	//armo el layout
	layout->add(new Label("P1 login:"));
	layout->add(txtPlayerOneLogin);
	layout->add(new Label("P1 pass:"));
	layout->add(txtPlayerOnePass);
	layout->add(new Label("P2 login:"));
	layout->add(txtPlayerTwoLogin);
	layout->add(new Label("P2 pass:"));
	layout->add(txtPlayerTwoPass);
	layout->add(btnBack);
	layout->add(btnStart);

	//muestro el layout armado junto con todos sus controles
	SDLControls::getInstance()->center(layout);
}

void Menu::pantallaRegistrarJugadores(Widget* widget, const SDL_Event& event){
	TextBox* txtNewLogin;
	TextBox* txtNewPass;
	TextBox* txtNewPassConf;
	Button* btnVolver;
	Button* btnRegistrar;
		
	//creo el campo de texto para el login
	txtNewLogin = new TextBox(Session::getInstance()->getNewPlayerLogin()!=NULL?Session::getInstance()->getNewPlayerLogin()->c_str():"");
	txtNewLogin->setCharWidth(20);
	txtNewLogin->setKeyDownHandler(&Session::setNewPlayerLogin);

	//creo el campo de texto para el pass
	txtNewPass = new PasswordTextBox(Session::getInstance()->getNewPlayerPass()!=NULL?Session::getInstance()->getNewPlayerPass()->c_str():"");
	txtNewPass->setCharWidth(20);
	txtNewPass->setKeyDownHandler(&Session::setNewPlayerPass);

	//creo el campo de texto para confirmar el pass
	txtNewPassConf = new PasswordTextBox(Session::getInstance()->getNewPlayerPassConf()!=NULL?Session::getInstance()->getNewPlayerPassConf()->c_str():"");
	txtNewPassConf->setCharWidth(20);
	txtNewPassConf->setKeyDownHandler(&Session::setNewPlayerPassConf);

	//creo el boton para registrar
	btnRegistrar = new Button("registrar");
	btnRegistrar->setClickHandler(&Menu::registrarNuevoJugador);

	//creo el boton para volver
	btnVolver = new Button("volver");
	btnVolver->setClickHandler(&Menu::pantallaInicial2);

	//creo un layout para organizar los widgtes
	GridLayout* layout = new GridLayout(2, 4);

	//armo la pantalla
	layout->add(new Label("login:"));
	layout->add(txtNewLogin);
	layout->add(new Label("pass:"));
	layout->add(txtNewPass);
	layout->add(new Label("confirmacion"));
	layout->add(txtNewPassConf);
	layout->add(btnVolver);
	layout->add(btnRegistrar);

	//limpio la pantalla
	SDLControls::getInstance()->clear();

	//muestro el layout armado junto con todos sus controles
	SDLControls::getInstance()->center(layout);
}


void Menu::pantallaInicial2(Widget* widget, const SDL_Event& event){

	Menu::pantallaInicial();
}

void Menu::pantallaInicial(){
	Button* btnStart;
	Button* btnRegister;
	Button* btnStats;
	Button* btnExit;

	//creo los botones
	btnStart = new Button("jugar");
	btnRegister = new Button("registrar jugador");
	btnStats = new Button("historial");
	btnExit = new Button("salir");

	//creo el layout
	GridLayout* layout = new GridLayout(1, 4);

	//asigno los handlers para el evento click
	btnStart->setClickHandler(&Menu::pantallaSeleccionJugadores);
	btnRegister->setClickHandler(&Menu::pantallaRegistrarJugadores);
	btnStats->setClickHandler(&Menu::pantallaEstadisticas);
	btnExit->setClickHandler(&Menu::accionSalir);

	//agrego los botones al layout
	layout->add(btnStart);
	layout->add(btnRegister);
	layout->add(btnStats);
	layout->add(btnExit);

	//reinicio la sesion
	//Session::getInstance()->clear();
	//blanqueo los passwords

	//limpio la pantalla
	SDLControls::getInstance()->clear();

	//muestro el layout armado junto con todos sus controles
	SDLControls::getInstance()->center(layout);
}

void Menu::pantallaEstadisticas(Widget* widget, const SDL_Event& event){
	Button* btnVerRankingPartidosGanados;
	Button* btnVerRankingPuntos;
	Button* btnVerRankingPartidosJugados;
	Button* btnVerRankingTiempoJugado;
	Button* btnVerComparacionJugadores;
	Button* btnVolver;
	GridLayout* layout;

	//creo los botones para ver las distintas estadisticas
	btnVerRankingPartidosGanados = new Button("partidos ganados");
	btnVerRankingPartidosGanados->setClickHandler(&Menu::rankingPartidosGanados);
	btnVerRankingPuntos = new Button("puntos");
	btnVerRankingPuntos->setClickHandler(&Menu::rankingPuntos);
	btnVerRankingPartidosJugados = new Button("partidos jugados");
	btnVerRankingPartidosJugados->setClickHandler(&Menu::rankingPartidosJugados);
	btnVerRankingTiempoJugado = new Button("tiempo jugado");
	btnVerRankingTiempoJugado->setClickHandler(&Menu::rankingTiempo);
	btnVerComparacionJugadores = new Button("comparacion");
	btnVerComparacionJugadores->setClickHandler(&Menu::pantallaComparacionJugadores);

	//creo el boton para volver atras
	btnVolver = new Button("volver");
	btnVolver->setWidth(100);
	btnVolver->setClickHandler(&Menu::pantallaInicial2);

	//creo un layout para organizarlos
	layout = new GridLayout(1, 6);

	//armo el layout
	layout->add(btnVerRankingPartidosGanados);
	layout->add(btnVerRankingPuntos);
	layout->add(btnVerRankingPartidosJugados);
	layout->add(btnVerRankingTiempoJugado);
	layout->add(btnVerComparacionJugadores);
	layout->add(btnVolver);

	//armo la pantalla
	layout->add(btnVerRankingPartidosGanados);
	layout->add(btnVerRankingPuntos);
	layout->add(btnVerRankingPartidosJugados);
	layout->add(btnVerRankingTiempoJugado);
	layout->add(btnVerComparacionJugadores);
	layout->add(btnVolver);

	//limpio la pantalla
	SDLControls::getInstance()->clear();

	//muestro la nueva pantalla
	SDLControls::getInstance()->center(layout);
}

void Menu::registrarNuevoJugador(Widget* widget, const SDL_Event& event){
	string* pass;
	string* passConf;
	string* login;

	//obtengo el nombre de usuario (login)
	login = Session::getInstance()->getNewPlayerLogin();

	//obtengo el password
	pass = Session::getInstance()->getNewPlayerPass();

	//obtengo la confirmacion
	passConf = Session::getInstance()->getNewPlayerPassConf();

	//si no se ingreso alguno de los valores
	if(pass == NULL || pass->empty() || passConf == NULL || passConf->empty() || login == NULL || login->empty())
		Menu::popUp(new Label("Debe llenar todos los campos"), &Menu::pantallaRegistrarJugadores);
	else//si ingreso el pass y la confirmacion, verifico
		if(pass == NULL || passConf == NULL)
			Menu::popUp(new Label("Debe ingresar un password y su confirmacion"), &Menu::pantallaRegistrarJugadores);
		else
			if(*pass != *passConf)
				Menu::popUp(new Label("La confirmacion no coincide"), &Menu::pantallaRegistrarJugadores);
			else
				if(DBService::getInstance()->isConexionCorrecta()){
					if(DBService::getInstance()->existeNombreUsuario(*Session::getInstance()->getNewPlayerLogin()))
						Menu::popUp(new Label("El nombre de usuario esta tomado"), &Menu::pantallaRegistrarJugadores);
					else{

						//reinicio la sesion
						Session::getInstance()->clear();

						//si llegue hasta aca todo esta bien y se puede dar de alta el nuevo usuario
						DBService::getInstance()->crearUsuario(*login, *pass);

						//luego informo que se creo exitosamente y vuelvo a la pantalla principal
						Menu::popUp(new Label("exito!"), &Menu::pantallaInicial2);
					}
				}else{
					Menu::popUp(new Label("Hubo un error en la conexion a la BD."), &Menu::pantallaRegistrarJugadores);
				}
}

void Menu::popUp(Widget* widget, CLICK_HANDLER_FUNC closeHandler){
	GridLayout* layout;
	Button* btnClose;

	//creo un layout para el popup
	layout = new GridLayout(1, 2);

	//creo un boton para cerrar el popup
	btnClose = new Button("cerrar");
	btnClose->setClickHandler(closeHandler);

	//armo la pantalla del poup
	layout->add(widget);
	layout->add(btnClose);

	//limpio la pantalla
	SDLControls::getInstance()->clear();

	//muestro el popup (el widget recibido y el boton para cerrarlo)
	SDLControls::getInstance()->center(layout);
}

bool Menu::confirm(const string& question){
	return false;
}

void Menu::login(Widget* widget, const SDL_Event& event){
}

Menu::Menu(){
	SDLControls::getInstance()->setHRes(800);
	SDLControls::getInstance()->setVRes(600);
	SDLControls::getInstance()->setDepth(32);

	SDLControls::getInstance()->setStartHandler(&Menu::pantallaInicial);
}

void Menu::setPantallaJuego(WRAPPER_JUEGO unaPantallaJuego){
	this->wrapperPantallaJuego = unaPantallaJuego;
}

void Menu::setPantallaQuitJuego(WRAPPER_JUEGO_QUIT unaFuncionDeSalida){
	this->wrapperPantallaQuitJuego = unaFuncionDeSalida;
}

void Menu::start(){
	SDLControls::getInstance()->start();
}

void Menu::iniciar(){
	// Seteo la pantalla para volver cuando salgo Jugar
	if(this->wrapperPantallaQuitJuego > 0)
		this->wrapperPantallaQuitJuego(&Menu::start);

	SDLControls::getInstance()->start();
}

void Menu::rankingPartidosGanados(Widget* widget, const SDL_Event& event){
	Menu::mostrarTabla("Partidos ganados", DBService::getInstance()->getRankingPartidosGanados());
}

void Menu::rankingPuntos(Widget* widget, const SDL_Event& event){
	Menu::mostrarTabla("Puntos", DBService::getInstance()->getRankingPuntos());
}

void Menu::rankingPartidosJugados(Widget* widget, const SDL_Event& event){
	Menu::mostrarTabla("Partidos jugados", DBService::getInstance()->getRankingPartidosJugados());
}

void Menu::pantallaComparacionJugadores(Widget* widget, const SDL_Event& event){
	TextBox* txtJugadorA;
	TextBox* txtJugadorB;
	Button* btnBack;
	Button* btnSend;
	GridLayout* layout;

	//creo los campos de texto para seleccionar los jugadores
	txtJugadorA = new TextBox(Session::getInstance()->getPlayerOneLogin()!=NULL?Session::getInstance()->getPlayerOneLogin()->c_str():"");
	txtJugadorA->setCharWidth(20);
	txtJugadorA->setKeyDownHandler(&Session::setPlayerOneLogin);

	txtJugadorB = new TextBox(Session::getInstance()->getPlayerTwoLogin()!=NULL?Session::getInstance()->getPlayerTwoLogin()->c_str():"");
	txtJugadorB->setCharWidth(20);
	txtJugadorB->setKeyDownHandler(&Session::setPlayerTwoLogin);

	//creo el boton para volver
	btnBack = new Button("volver");
	btnBack->setClickHandler(&Menu::pantallaEstadisticas);

	//creo el boton para ver el listado
	btnSend = new Button("ver");
	btnSend->setClickHandler(&Menu::compararJugadores);

	//creo el layout y armo la pantalla
	layout = new GridLayout(2, 3);

	layout->add(new Label("1er jugador:"));
	layout->add(txtJugadorA);
	layout->add(new Label("2do jugador:"));
	layout->add(txtJugadorB);
	layout->add(btnBack);
	layout->add(btnSend);

	//limpio la pantalla
	SDLControls::getInstance()->clear();

	//muestro la nueva pantalla (el layout armado)
	SDLControls::getInstance()->center(layout);
}

void Menu::rankingTiempo(Widget* widget, const SDL_Event& event){
	Menu::mostrarTabla("Tiempo", DBService::getInstance()->getRankingTiempoJugado());
}

void Menu::compararJugadores(Widget* widget, const SDL_Event& event){
	Lista<ItemComparativoEstadistica>* datos;
	IteradorLista<ItemComparativoEstadistica>* itDatos;
	ItemComparativoEstadistica* item;
	GridLayout* layout;
	Button* btnVolver;
	Button* btnVolverMenu;

	//verifico si se ingresaron ambos usuarios
	if(Session::getInstance()->getPlayerOneLogin() != NULL && !Session::getInstance()->getPlayerOneLogin()->empty() && Session::getInstance()->getPlayerTwoLogin() != NULL && !Session::getInstance()->getPlayerTwoLogin()->empty()){

		//verifico que haya conexion con la base de datos
		if(DBService::getInstance()->isConexionCorrecta()){

			//obtengo los datos
			datos = DBService::getInstance()->getComparacion(*Session::getInstance()->getPlayerOneLogin(), *Session::getInstance()->getPlayerTwoLogin());

			//si se obtuvieron datos
			if(datos != NULL && !datos->estaVacia()){

				//creo un layout para mostrar la tabla
				layout = new GridLayout(4, datos->tamanio() + 2);

				//agrego los titulos
				layout->add(new Label("Ganador"));
				layout->add(new Label("ptos ganador"));
				layout->add(new Label("ptos perdedor"));
				layout->add(new Label("tiempo"));

				//obtengo un iterador
				itDatos = new IteradorLista<ItemComparativoEstadistica>(datos);

				//uso el iterador para recorrer y mostrar los datos
				while(itDatos->tieneSiguiente()){

					//obtengo el item
					item = itDatos->siguiente();

					layout->add(new Label(item->getGanador()->c_str()));
					layout->add(new Label(item->getPuntosGanador()->c_str()));
					layout->add(new Label(item->getPuntosPerdedor()->c_str()));
					layout->add(new Label(item->getTiempo()->c_str()));
				}

				//finalmente creo y agrego el boton para volver
				btnVolver = new Button("estadisticas");
				btnVolver->setClickHandler(&Menu::pantallaEstadisticas);

				btnVolverMenu = new Button("menu");
				btnVolverMenu->setClickHandler(&Menu::pantallaInicial2);

				layout->add(btnVolver);
				layout->add(btnVolverMenu);

				//limpio la pantalla
				SDLControls::getInstance()->clear();

				//limpio la sesion
				Session::getInstance()->clear();

				//muestro la tabla
				SDLControls::getInstance()->center(layout);
			}
			else
				Menu::popUp(new Label("No hay datos"), &Menu::pantallaComparacionJugadores);
		}
		else
			Menu::popUp(new Label("No se pudo conectar con la BD"), &Menu::pantallaComparacionJugadores);
	}
	else
		Menu::popUp(new Label("Debe ingresar los dos usuarios"), &Menu::pantallaComparacionJugadores);
}

void Menu::mostrarTabla(const string& descripcion, Lista<ItemEstadistica>* datos){
	GridLayout* layout;
	Button* btnVolver;
	Button* btnVolverMenu;
	IteradorLista<ItemEstadistica>* itDatos;
	ItemEstadistica* item;
	Label* lblColJugador;
	Label* lblColDesc;

	if(datos != NULL && !datos->estaVacia()){
		//creo un layout para la tabla
		layout = new GridLayout(2, datos->tamanio() + 2);

		//armo la tabla
		layout->add(lblColJugador = new Label("Jugador"));
		lblColJugador->setWidth(50);
		layout->add(lblColDesc = new Label(descripcion.c_str()));
		lblColDesc->setWidth(descripcion.length());

		//layout->add(new Label(descripcion.c_str()));

		//obtengo un iterador
		itDatos = new IteradorLista<ItemEstadistica>(datos);

		//recorro los datos mediante el iterador y armo la tabla
		while(itDatos->tieneSiguiente()){

			//obtengo el siguiente item
			item = itDatos->siguiente();

			//agrego la fila a la tabla
			layout->add(new Label(item->getUsuario()->c_str()));
			layout->add(new Label(item->getValor()->c_str()));
		}

		//finalmente creo y agrego el boton para volver
		btnVolver = new Button("estadisticas");
		btnVolver->setClickHandler(&Menu::pantallaEstadisticas);

		btnVolverMenu = new Button("menu");
		btnVolverMenu->setClickHandler(&Menu::pantallaInicial2);

		layout->add(btnVolver);
		layout->add(btnVolverMenu);

		//limpio la pantalla
		SDLControls::getInstance()->clear();

		//muestro la tabla
		SDLControls::getInstance()->center(layout);
	}
	else
		Menu::popUp(new Label("No hay datos"), &Menu::pantallaEstadisticas);
}

Menu::~Menu(){
}